// $URL: http://mingw-lib.googlecode.com/svn/trunk/working/avcodec_to_widget_9/video/t_video_frame.h $
// $Rev: 317 $
// $Author: akio.miyoshi $
// $Date:: 2010-07-31 08:09:41 +0000#$

#ifndef T_VIDEO_FRAME_H
#define T_VIDEO_FRAME_H

#include "stable.h"
#include "t_av_packet.h"

class T_Video_Frame
{
public:
    explicit T_Video_Frame(T_AV_Packet *a_packet)
        : m_packet(a_packet)
    {
        //Q_ASSERT(m_packet);
    }
    ~T_Video_Frame()
    {
        delete m_packet;
    }
    bool isNull()
    {
        return (!m_packet);
    }
    qint64 timing()
    {
        return m_packet->timing();
    }
    int frameNo()
    {
        return m_packet->frameNo();
    }
    //[decodeToQImage()]
    QImage decodeVideoToQImage(const QSize &a_size, int a_depth)
    {
        return this->m_packet->decodeVideoToQImage(a_size, a_depth);
    }
protected:
    T_AV_Packet *m_packet;
    QImage m_image;
};

class T_Video_Frame_Queue : public T_RecursiveAtomicObject
{
    Q_OBJECT
protected:
    class T_Box_Player_Context *m_player_ctx;
    QQueue<T_Video_Frame *> packet_queue;
    int m_enqueue_count;
    bool m_complete;
public:
    explicit T_Video_Frame_Queue(class T_Box_Player_Context *a_player_ctx)
        : m_player_ctx(a_player_ctx)
        , m_enqueue_count(0)
        , m_complete(false)
    {
    }
    ~T_Video_Frame_Queue()
    {
    }
    bool isComplete()
    {
        return m_complete;
    }
    int size()
    {
        QMutexLocker v_lock(this);
        Q_UNUSED(v_lock);
        return packet_queue.size();
    }
    void clear()
    {
        QMutexLocker v_lock(this);
        Q_UNUSED(v_lock);
        while(T_Video_Frame *v = this->dequeue())
        {
            delete v;
        }
        m_enqueue_count = 0;
        m_complete = false;
    }
    void enqueue(T_Video_Frame *a_av_packet)
    {
        QMutexLocker v_lock(this);
        Q_UNUSED(v_lock);
        Q_ASSERT(!m_complete);
        if(a_av_packet==NULL)
        {
            a_av_packet = new T_Video_Frame(NULL);
            packet_queue.enqueue(a_av_packet);
            m_complete = true;
            return;
        }
        packet_queue.enqueue(a_av_packet);
    }
    T_Video_Frame *dequeue()
    {
        QMutexLocker v_lock(this);
        Q_UNUSED(v_lock);
        if(packet_queue.size()==0) return NULL;
        return packet_queue.dequeue();
    }
    T_Video_Frame *head()
    {
        QMutexLocker v_lock(this);
        Q_UNUSED(v_lock);
        if(packet_queue.size()==0) return NULL;
        return packet_queue.head();
    }
    T_Video_Frame *last()
    {
        QMutexLocker v_lock(this);
        Q_UNUSED(v_lock);
        if(packet_queue.size()==0) return NULL;
        return packet_queue.last();
    }
    T_Video_Frame *value(int i)
    {
        QMutexLocker v_lock(this);
        Q_UNUSED(v_lock);
        if(i<0) return NULL;
        if(i>=packet_queue.size()) return NULL;
        return packet_queue.value(i);
    }
    qint64 duration()
    {
        QMutexLocker v_lock(this);
        Q_UNUSED(v_lock);
        if(m_complete)
        {
            return LONG_LONG_MAX;
        }
        if(packet_queue.size()==0) return 0;
        return (last()->timing() - head()->timing());
    }
};

#endif // T_VIDEO_FRAME_H
